package com.songcan.oauth.confinguration;

import com.alibaba.druid.pool.DruidDataSource;
import com.songcan.common.config.JsonConfiguration;
import com.songcan.common.config.MybatisConfiguration;
import com.songcan.common.config.RedisConfiguration;
import com.songcan.common.context.JwtFilter;
import com.songcan.common.handle.GlobalExceptionHandler;
import com.songcan.common.utils.HashPasswordService;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler;
import org.springframework.stereotype.Component;


import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.List;

@Component
@Import({RedisConfiguration.class, GlobalExceptionHandler.class, JsonConfiguration.class,MybatisConfiguration.class})
@MapperScan(basePackages = "com.songcan.oauth.mapper*")
public class CoreConfiguration {

    @Value("${security.credentials.algorithmName}")
    private String algorithmName;

    @Value("${security.credentials.iterations}")
    private int iterations;


    /**
     * 配置解决 spring-security-oauth问题
     * https://github.com/spring-projects/spring-security-oauth/issues/730
     *
     * @param applicationContext ApplicationContext
     * @return OAuth2WebSecurityExpressionHandler
     */
    @Bean
    public OAuth2WebSecurityExpressionHandler oAuth2WebSecurityExpressionHandler(ApplicationContext applicationContext) {
        OAuth2WebSecurityExpressionHandler expressionHandler = new OAuth2WebSecurityExpressionHandler();
        expressionHandler.setApplicationContext(applicationContext);
        return expressionHandler;
    }

    // @ConfigurationProperties() 将配置文件中的连接池配置添加到数据源
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean(initMethod = "init")
    @Primary
    public DruidDataSource druid() {
        return new DruidDataSource();
    }

    /**
     * 进行所有路由拦截,可进行定义匹配规则
     * @param redisTemplate
     * @return
     */
    @Bean
    public FilterRegistrationBean filterRegistrationBean(RedisTemplate redisTemplate) {
        FilterRegistrationBean<JwtFilter> registrationBean = new FilterRegistrationBean<>();
        JwtFilter httpBasicFilter = new JwtFilter(redisTemplate);
        registrationBean.setFilter(httpBasicFilter);
        List<String> urlPatterns = new ArrayList<>();
        urlPatterns.add("/rest/*");
        registrationBean.setUrlPatterns(urlPatterns);
        return registrationBean;
    }


    @Bean("hashPasswordService")
    public HashPasswordService hashPasswordService(){
            return new HashPasswordService(algorithmName,iterations);
    }
}
